package com.gyj.zookeeper.ZookeeperApi;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * Created by Gao on 2018/10/23.
 * 核心类Zookeeper类，相关方法：
 * connect:连接到zookeeper集合
 * create:创建znode
 * exist：检查znode是否存在及其信息
 * getData：从特定的znode获取数据
 * setData:在特定的znode中设置数据
 * getChildren:获取特定的znode中的所有子节点
 * delete:删除特定的znode及其子项
 * close:关闭连接
 * <p>
 * ZooKeeper类通过其构造函数提供connect power能。构造函数的签名如下：
 * ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)
 * connectionString - ZooKeeper集合主机。
 * sessionTimeout - 会话超时（以毫秒为单位）。
 * watcher  - 实现“监视器”界面的对象.ZooKeeper集合通过监视器对象返回连接状态。
 * 创建一个新的帮助类ZooKeeperConnection，并添加一个方法connect。 连接方法创建一个ZooKeeper对象，连接到ZooKeeper集合，然后返回对象。
 * 这里CountDownLatch用于停止（等待）主进程，直到客户端与动物园管理员集合连接。
 * ZooKeeper集合通过监视器回调来回复连接状态。一旦客户端与ZooKeeper集合连接，监视器回调就会被调用，
 * 并且监视器回调函数调用CountDownLatch的countDown方法来释放锁，在主进程中等待。
 */
public class ZKConnection {

    private ZooKeeper zooKeeper = null;
    private final CountDownLatch connectedSignal = new CountDownLatch(1);

    public ZooKeeper connect(String host) throws IOException, InterruptedException {
        zooKeeper = new ZooKeeper(host, 5000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                    connectedSignal.countDown();
                }
            }
        });
        connectedSignal.await();

        return zooKeeper;
    }

    public void close() throws InterruptedException {
        zooKeeper.close();
    }
}
